/*
 * Copyright 2008 The Brui Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

package com.googlecode.brui.beans;

/**
 * Base {@link Validator} implementation for convenience which handles type
 * checking, null checking, and validation checking.
 * 
 * @param <T> the type which can be understood by this {@link AbstractValidator}.
 */
abstract class AbstractValidator<T> implements Validator<T> {

	/**
	 * Get the textual representation of the given object. Performs null check
	 * and a type check before delegating to the subtype. Implementors need not
	 * perform null and type checking.
	 * 
	 * @return empty string if the object is <code>null</code>, otherwise
	 *         delegates to the subtype.
	 * @throws IllegalArgumentException if the given object is not an instance of
	 *         {Validator#getType()}.
	 * @see AbstractValidator#getTextValue(Object)
	 */
	@Override
	public final String asText(final T object) {
		if (object == null) {
			return "";
		}
		if (!getType().isAssignableFrom(object.getClass())) {
			throw new IllegalArgumentException("Invalid type for this validator: " + object.getClass());
		}
		return getTextValue(object);
	}

	/**
	 * Get the object represented by the given text. Implementors need not check
	 * for validity.
	 * 
	 * @throws NullPointerException if the given text is <code>null</code>.
	 * @throws ValidationException if the given text is not valid according to
	 *         {@link Validator#isValid(String)}.
	 * @see AbstractValidator#getObjectValue(String)
	 */
	@Override
	public final T fromText(final String text) {
		if (text == null) {
			throw new NullPointerException("Cannot validate a null value.");
		}
		if (!isValid(text)) {
			throw new ValidationException(text, getType());
		}
		if (text == "") {
			return null;
		}
		return getObjectValue(text);
	}

	/**
	 * Convert an object to its textual representation.
	 * 
	 * @param object an object which must be an instance of
	 *        {@link Validator#getType()}.
	 * @return the textual representation of the given object.
	 */
	abstract String getTextValue(T object);

	/**
	 * Convert text to an object.
	 * 
	 * @param text some input which must be valid according to
	 *        {@link Validator#isValid(String)}.
	 * @return an object which is represented by the text.
	 */
	abstract T getObjectValue(String text);
}
